package com.rybbaby.tss.core.web.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.rybbaby.tss.core.annotation.RequestLog;
import com.rybbaby.tss.core.annotation.validator.StringValidator;
import com.rybbaby.tss.core.interceptors.DateConvertEditor;
import com.rybbaby.tss.core.utils.EncryptPasswordUtil;
import com.rybbaby.tss.core.utils.JSONUtil;
import com.rybbaby.tss.core.utils.SequenceUtil;
import com.rybbaby.tss.platform.consts.PlatformCommonConsts;
import com.rybbaby.tss.platform.sysAdminUser.entity.SysAdminUser;
import com.rybbaby.tss.platform.sysAdminUserJoinSysRole.entity.SysAdminUserJoinSysRole;
import com.rybbaby.tss.platform.sysFiles.service.ISysFilesService;
import com.rybbaby.tss.platform.websocket.service.PlatformWebsocketMsgService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;

/**
 * @author 谢进伟
 * @description 所有controller类的基础类
 * @createDate 2016-1-28 上午10:04:20
 */
@Controller
@RequestMapping(value = "/")
public class BaseController {
    @Autowired
    private ISysFilesService sysFilesService;
    /**
     * 搜索条件集合 key
     **/
    protected final String SEARCH_MAP = PlatformCommonConsts.SEARCH_MAP;
    /**
     * 分页模型 key
     **/
    protected final String PAGE_BEAN = PlatformCommonConsts.PAGE_BEAN;
    /**
     * 列表搜索表单
     **/
    protected final String SEARCH_FORM = PlatformCommonConsts.SEARCH_FORM;
    /**
     * 登陆成功Session保存的用法对象
     **/
    protected final String SESSION_LOGINUSER_OBJ = PlatformCommonConsts.SESSION_LOGINUSER_OBJ;
    /**
     * 登陆成功Session保存的用法对象Id
     **/
    protected final String SESSION_LOGINUSER_OBJ_ID = PlatformCommonConsts.SESSION_LOGINUSER_OBJ_ID;
    /**
     * 登陆成功Session保存用户所有用的所有角色的Id
     */
    protected final String SESSION_LOGINUSER_ROLES = "loginUserRoles";
    /**
     * 登陆成功Session保存用户所有用的所有角色
     */
    protected final String SESSION_LOGINUSER_ROLEIDS = "loginUserRoleIds";
    /**
     * 当前请求对象
     **/
    @Autowired
    protected HttpServletRequest request;
    /**
     * webSocket消息服务
     */
    @Autowired
    protected PlatformWebsocketMsgService platformWebsocketMsgService;
    /**
     * 日志对象
     **/
    protected Logger log;

    public BaseController() {
        log = Logger.getLogger(this.getClass());
    }

    /**
     * 获取request
     *
     * @return request
     */
    public HttpServletRequest getRequest() {
        return this.request;
    }

    /**
     * 设置request
     *
     * @param request request
     */
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    /**
     * 获取session
     *
     * @return session
     */
    public HttpSession getSession() {
        return this.request.getSession();
    }

    /**
     * 切换视图
     *
     * @param viewPath 视图相对路径
     * @return
     */
    @RequestMapping(value = "switchView")
    @RequestLog(content = "查看视图")
    public ModelAndView switchView(@RequestParam(required = true) @StringValidator(length = 1000) String viewPath) {
        ModelAndView mav = new ModelAndView(viewPath, request.getParameterMap());
        String serializeNum = SequenceUtil.getUpperCaseUUID();
        mav.addObject("serializeNum", serializeNum);
        return mav;
    }

    /**
     * 打印调试日志信息
     *
     * @param message 调试信息
     */
    protected void debug(String message) {
        if (log.isDebugEnabled()) {
            log.debug(message);
        }
    }

    /**
     * 打印日志信息
     *
     * @param message
     */
    protected void info(String message) {
        if (log.isInfoEnabled()) {
            log.info(message);
        }
    }

    /**
     * 打印调试日志信息(包含异常信息)
     *
     * @param message 调试信息
     * @param t
     */
    protected void debug(String message, Throwable t) {
        if (log.isDebugEnabled()) {
            log.debug(message, t);
        }
    }

    /**
     * 打印日志信息(包含异常信息)
     *
     * @param message 调试信息
     * @param t
     */
    protected void info(String message, Throwable t) {
        if (log.isInfoEnabled()) {
            log.info(message, t);
        }
    }

    /**
     * 打印错误信息
     *
     * @param message 错误信息
     */
    protected void error(String message) {
        log.error(message);
    }

    /**
     * 打印错误信息
     *
     * @param message 错误信息
     * @param t
     */
    protected void error(String message, Throwable t) {
        log.error(message, t);
    }

    /**
     * 缓存登录对象信息
     *
     * @param loginUser    登录用户对象
     * @param joinSysRoles
     */
    protected void cacheLoginUsr(SysAdminUser loginUser, List<SysAdminUserJoinSysRole> joinSysRoles) {
        if (loginUser != null) {
            //缓存登陆管理员信息
            String loginUserId = loginUser.getId();
            log.info("login user id:" + loginUserId);
            this.getSession().setAttribute(SESSION_LOGINUSER_OBJ, loginUser);
            this.getSession().setAttribute(SESSION_LOGINUSER_OBJ_ID, loginUserId);
            //缓存角色相关信息
            if (joinSysRoles != null && !joinSysRoles.isEmpty()) {
                StringBuffer roleIds = null;
                roleIds = new StringBuffer();
                for (SysAdminUserJoinSysRole joinSysRole : joinSysRoles) {
                    roleIds.append("#").append(joinSysRole.getRoleId()).append("#");
                }
                log.info("login user have all role id:" + roleIds);
                this.getSession().setAttribute(SESSION_LOGINUSER_ROLEIDS, roleIds);
                this.getSession().setAttribute(SESSION_LOGINUSER_ROLES, joinSysRoles);
            }
        }
    }

    /**
     * @return 获取当前登录用户
     */
    public SysAdminUser getLoginUser() {
        if (request != null) {
            HttpSession session = getSession();
            Object loginUserObj = session.getAttribute(SESSION_LOGINUSER_OBJ);
            if (loginUserObj != null && loginUserObj instanceof SysAdminUser) {
                SysAdminUser loginUser = (SysAdminUser) loginUserObj;
                return loginUser;
            }
        }
        return null;
    }

    /**
     * @return 获取登录用的id
     */
    public Object getLoginUserId() {
        SysAdminUser loginUser = this.getLoginUser();
        if (loginUser != null) {
            return loginUser.getId();
        } else {
            return null;
        }
    }

    /**
     * 移除登录用户信息(退出登录时调用)
     *
     * @return
     */
    protected boolean removeLoginUser() {
        getSession().invalidate();
        return getLoginUser() == null;
    }

    /**
     * 用密码加密
     *
     * @param entity 用户对象
     * @return
     */
    protected String encryptPassword(SysAdminUser entity) {
        return EncryptPasswordUtil.encryptAdminPassword(entity.getId(), entity.getCreateTime(), entity.getUserPassword());
    }

    /**
     * 将前台传递过来的日期格式的字符串，自动转化为Date类型
     *
     * @param binder
     */
    @InitBinder
    protected void initBinder(ServletRequestDataBinder binder) {
        HttpSession session = getSession();
        ServletContext servletContext = session.getServletContext();
        servletContext.setAttribute("ctx", servletContext.getContextPath());
        binder.registerCustomEditor(Date.class, new DateConvertEditor());
    }

    /**
     * 响应远程异步验证
     *
     * @param valid 验证结果
     * @return
     * @throws JsonProcessingException
     */
    protected String responseRemoteValidate(boolean valid) throws JsonProcessingException {
        Map<String, Object> remoteResultMap = new HashMap<String, Object>();
        remoteResultMap.put("valid", valid);
        remoteResultMap.put("resCode", 200);
        remoteResultMap.put("resMsg", "验证成功!");
        return JSONUtil.toJsonStr(remoteResultMap);
    }

    /**
     * 对请求带的token与session中的token进行对比，防止重复提交
     *
     * @param request 请求对象
     * @return true 重复提交，false 首次提交
     */
    protected boolean checkToken(HttpServletRequest request) {
        String newToken = request.getParameter("token");
        Object oldToken = request.getSession().getAttribute("token");
        if (oldToken == null) {
            return false;
        } else {
            return oldToken.equals(newToken);
        }
    }

    /**
     * 获取请求参数,此方法会自动对传入的参数进行url解码(解码编码格式为UTF-8)
     *
     * @param paramsName 参数名称
     * @return
     * @throws UnsupportedEncodingException
     */
    protected String getParameter(String paramsName) {
        String parameter = request.getParameter(paramsName);
        try {
            return this.decode(parameter);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 对字符串进行URL解码
     *
     * @param str 需要解码的字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    protected String decode(String str) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(str)) {
            return str;
        }
        return this.decode(str, "UTF-8");
    }

    /**
     * 对字符串进行URL解码
     *
     * @param str               需要解码的字符串
     * @param characterEncoding 编码格式(若此参数为null，则会以UTF-8方式进行编码)
     * @return
     * @throws UnsupportedEncodingException
     */
    protected String decode(String str, String characterEncoding) throws UnsupportedEncodingException {
        if (StringUtils.isEmpty(str)) {
            return str;
        }
        if (StringUtils.isEmpty(characterEncoding)) {
            characterEncoding = "UTF-8";
        }
        str = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
        str = str.replaceAll("\\+", "%2B");
        str = URLDecoder.decode(str, characterEncoding);
        return str;
    }

    /**
     * 获取请求参数集合，会自动的尝试为参数进行RUL解码
     *
     * @param request 请求对象
     * @return
     */
    protected Map<String, String[]> getParameterMap(HttpServletRequest request) {
        Map<String, String[]> params = new HashMap<String, String[]>();
        Map<String, String[]> parameterMap = request.getParameterMap();
        Iterator<String> iterator = parameterMap.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String[] parameterValues = request.getParameterValues(key);
            String[] decodeParameter = null;
            if (parameterValues != null && parameterValues.length > 0) {
                decodeParameter = new String[parameterValues.length];
                for (int i = 0; i < parameterValues.length; i++) {
                    try {
                        decodeParameter[i] = this.decode(parameterValues[i]);
                    } catch (UnsupportedEncodingException e) {
                        decodeParameter[i] = parameterValues[i];
                    }
                }
            }
            params.put(key, decodeParameter);
        }
        return params;
    }


    /**
     * 获取当前登录人的所哟角色id
     *
     * @return
     */
    protected List<String> getLoginAdminRoles() {
        String sql = "SELECT sr.roleName roleName FROM sys_admin_user_join_sys_role jsr left JOIN sys_role  sr on jsr.roleId=sr.id WHERE adminUserId =?";
        List<String> roleList = new ArrayList<>();
        String loginAdminUserId = this.getLoginUser().getId();
        if (!StringUtils.isEmpty(loginAdminUserId)) {
            List<Map<String, Object>> roleMapList = this.sysFilesService.findForJdbc(sql, new Object[]{loginAdminUserId});
            if (roleMapList != null && !roleMapList.isEmpty()) {
                roleMapList.forEach((Map<String, Object> map) -> {
                    Object roleId = map.get("roleName");
                    if (roleId != null) {
                        roleList.add(roleId.toString());
                    }
                });
            }
        }
        return roleList;
    }
    /**
     * 获取当前登录人的所哟角色id
     *
     * @return
     */
    protected List<String> getLoginAdminRoles(String loginAdminUserId) {
        String sql = "SELECT sr.roleName roleName FROM sys_admin_user_join_sys_role jsr left JOIN sys_role  sr on jsr.roleId=sr.id WHERE adminUserId =?";
        List<String> roleList = new ArrayList<>();
        //String loginAdminUserId = this.getLoginUser().getId();
        if (!StringUtils.isEmpty(loginAdminUserId)) {
            List<Map<String, Object>> roleMapList = this.sysFilesService.findForJdbc(sql, new Object[]{loginAdminUserId});
            if (roleMapList != null && !roleMapList.isEmpty()) {
                roleMapList.forEach((Map<String, Object> map) -> {
                    Object roleId = map.get("roleName");
                    if (roleId != null) {
                        roleList.add(roleId.toString());
                    }
                });
            }
        }
        return roleList;
    }


    /**
     * 根据角色名称和园所id查询员工信息
     *
     * @param roleName
     * @param schoolId
     * @return
     */
    protected List<String> getUserIdByRoleAndSchololId(String schoolId) {
        StringBuffer sql = new StringBuffer();
        List<Map<String, Object>> adminUserMapList=new ArrayList<>();
        sql.append("select sau.id from sys_admin_user  sau  left JOIN sys_admin_user_join_sys_role  jsr \n" +
                "on sau.id=jsr.adminUserId  \n" +
                "left JOIN sys_role  sr \n" +
                "on sr.id=jsr.roleId\n" +
                "WHERE  sau.schoolId=?\n");
      /*  if (roleName.equals(RoleConsts.TSS_ROLE_KINDERGARTEN_LEADER)) {
            adminUserMapList = this.sysFilesService.findForJdbc(sql.toString(), new Object[]{ schoolId});
        }else{
            sql.append(" and  sr.roleName =?");
            adminUserMapList = this.sysFilesService.findForJdbc(sql.toString(), new Object[]{schoolId,roleName});
        }*/
        adminUserMapList = this.sysFilesService.findForJdbc(sql.toString(), new Object[]{ schoolId});
        List<String> adminUserList = new ArrayList<>();
        if (adminUserMapList != null && !adminUserMapList.isEmpty()) {
            adminUserMapList.forEach((Map<String, Object> map) -> {
                Object adminUserId = map.get("id");
                if (adminUserId != null) {
                    adminUserList.add(adminUserId.toString());
                }
            });
        }
        return adminUserList;
    }

    /**
     * 获取当前登录人的所哟角色id
     *
     * @return
     */
    protected List<Map<String, Object>> getAdminRoles(String adminUserId) {
        String sql = "SELECT sr.roleName roleName FROM sys_admin_user_join_sys_role jsr left JOIN sys_role  sr on jsr.roleId=sr.id WHERE adminUserId =?";
        List<Map<String, Object>> roleMapList = this.sysFilesService.findForJdbc(sql, new Object[]{adminUserId});
        return roleMapList;
    }

}
